package net.neptech.websocket;

import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Component
@ServerEndpoint(value = "/websocket/ws/subtitle/{conferenceId}")
public class SubtitleWebSocket {

    private static final ConcurrentHashMap<String, Set<Session>> subscribers = new ConcurrentHashMap<>();
    // 用于从 Session 中获取 cid 的 key
    private static final String CONFERENCE_ID_KEY = "conferenceId";
    @OnOpen
    public void onOpen(@PathParam("conferenceId") String conferenceId, Session session) {
        // 把 cid 保存到 Session 属性中
        session.getUserProperties().put(CONFERENCE_ID_KEY, conferenceId);

        subscribers
                .computeIfAbsent(conferenceId, k -> ConcurrentHashMap.newKeySet())
                .add(session);

        System.out.println("字幕客户端加入: " + conferenceId + " | 当前房间人数: " + subscribers.get(conferenceId).size());
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        // 从 Session 中获取之前保存的 cid
        String conferenceId = (String) session.getUserProperties().get(CONFERENCE_ID_KEY);

        if (conferenceId == null) {
            System.err.println("无法获取会议ID，Session丢失");
            return;
        }

        System.out.println("收到客户端消息: " + message + " | 会议: " + conferenceId);

        // 🔔 广播给同个会议的所有客户端
        Set<Session> sessions = subscribers.get(conferenceId);
        if (sessions != null) {
            sessions.forEach(s -> {
                try {
                    s.getBasicRemote().sendText(message);
                } catch (IOException e) {
                    System.err.println("推送消息失败: " + e.getMessage());
                    e.printStackTrace();
                }
            });
        }
    }

    @OnClose
    public void onClose(Session session) {
        // 从 Session 获取 cid
        String conferenceId = (String) session.getUserProperties().get(CONFERENCE_ID_KEY);
        if (conferenceId == null) return;

        Set<Session> sessions = subscribers.get(conferenceId);
        if (sessions != null) {
            sessions.remove(session);
            if (sessions.isEmpty()) {
                subscribers.remove(conferenceId);
            }
        }
        System.out.println("字幕客户端离开: " + conferenceId);
    }


    @OnError
    public void onError(Session session, Throwable throwable) {
        log.error("字幕推送错误", throwable);
    }

    // 外部调用此方法推送字幕
    public static void pushSubtitle(String conferenceId, String speaker, String text) {
        Set<Session> sessions = subscribers.get(conferenceId);
        if (sessions != null) {
            String json = String.format(
                    "{\"type\":\"speech-text\",\"data\":{\"speaker\":\"%s\",\"text\":\"%s\",\"time\":\"%s\"}}",
                    speaker, text, LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))
            );
            sessions.forEach(session -> {
                session.getAsyncRemote().sendText(json);
            });
        }
    }

    // 提供给其他服务调用，推送字幕
    public static void broadcastToConference(String cid, String message) {
        Set<Session> sessions = subscribers.get(cid);
        if (sessions != null) {
            sessions.forEach(s -> {
                try {
                    s.getBasicRemote().sendText(message);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
        }
    }
    // SubtitleWebSocket.java
    public static void pushSubtitleEx(String conferenceId, String speaker, String text, boolean partial) {
        Set<Session> sessions = subscribers.get(conferenceId);
        if (sessions != null) {
            String json = String.format(
                    "{\"type\":\"speech-text\",\"data\":{\"speaker\":\"%s\",\"text\":\"%s\",\"partial\":%s,\"time\":\"%s\"}}",
                    escape(speaker), escape(text), partial ? "true" : "false",
                    java.time.LocalTime.now().toString()
            );
            sessions.forEach(session -> session.getAsyncRemote().sendText(json));
        }
    }

    // 简单转义，避免引号冲突
    private static String escape(String s) {
        if (s == null) return "";
        return s.replace("\\","\\\\").replace("\"","\\\"");
    }

}
